package com.uploadFile.controller;

import com.uploadFile.config.OssConfig;
import com.uploadFile.entity.dto.FileUploadDTO;
import com.uploadFile.result.Result;
import com.uploadFile.service.FileExpirationService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URLEncoder;

/**
 * @Author pl711@qq.com
 * @PackageName uploadFile
 * @Package com.controller.uploadFile
 * @Date 2024/5/10 23:31
 * @Version 1.0
 */
@Api(tags = "文件上传或下载")
@RestController
@RequestMapping("/file")
public class FileController {

    @Autowired
    private OssConfig ossConfig;

    @Autowired
    private FileExpirationService fileExpirationService;

    //上传文件接口
    @ApiOperation(value = "通用上传文件的接口")
    @PostMapping("/upload")
    public Result<FileUploadDTO> uploadFile(@RequestParam("file") MultipartFile file, @RequestParam("fileType") String fileType) throws IOException {
        //数据库保存里面
        String path = ossConfig.uploadFile(file, fileType);

        fileExpirationService.storeFileWithExpiry(path);
        //文件回显路径
        String url = "https://" + ossConfig.getBucketName() + "." + ossConfig.getEndpoint() + "/" + path;
        return Result.success(new FileUploadDTO(url, path));
    }

    @ApiOperation(value = "通用删除文件的接口")
    @PostMapping("/delete")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "objectName", value = "填写不包含Bucket名称在内的Object完整路径", required = true)
    })
    public Result<String> deleteFile(@RequestParam("objectName") String objectName) throws IOException {
        ossConfig.deleteObject(objectName);
        return Result.success();
    }


    @ApiOperation(value = "通用下载文件的接口")
    @PostMapping("/download")
    public ResponseEntity<ByteArrayResource> downloadFile(@RequestParam("objectName") String objectName) throws IOException {
        ByteArrayOutputStream outputStream = ossConfig.getObject(objectName);
        // 初始化HTTP响应头
        HttpHeaders httpHeaders = new HttpHeaders();

        // 解析文件后缀
        String suffix = objectName.substring(objectName.lastIndexOf("."));
        // 生成时间戳作为文件名的一部分，避免重复
        String time = String.valueOf(System.currentTimeMillis());
        objectName = "yy下载站_" + time + suffix;
        System.out.println("objectName = " + objectName);
        // 设置Content-Disposition头，用于指定浏览器以下载方式打开文件，并设置文件名
        httpHeaders.setContentDispositionFormData("yy下载站_" + time, URLEncoder.encode(objectName, "utf-8"));
        // 设置缓存控制头，确保文件不会被缓存
        httpHeaders.add("Cache-Control", "no-cache, no-store, must-revalidate");
        httpHeaders.add("Pragma", "no-cache");
        httpHeaders.add("Expires", "0");

        // 设置响应内容类型为二进制流
        httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);

        // 将文件内容封装为ByteArrayResource，用于响应
        ByteArrayResource byteArrayResource = new ByteArrayResource(outputStream.toByteArray());

        return ResponseEntity.ok()
                .headers(httpHeaders)
                .contentLength(byteArrayResource.contentLength())
                .body(byteArrayResource);
    }
}
